a tool for shared writing and social publishing
at refactor/standard.site 107 lines 3.4 kB view raw
1import { z } from "zod"; 2import { makeRoute } from "../lib"; 3import type { Env } from "./route"; 4import { AtUri } from "@atproto/syntax"; 5import { getFactsFromHomeLeaflets } from "./getFactsFromHomeLeaflets"; 6import { normalizeDocumentRecord } from "src/utils/normalizeRecords"; 7import { ids } from "lexicons/api/lexicons"; 8 9export type GetPublicationDataReturnType = Awaited< 10 ReturnType<(typeof get_publication_data)["handler"]> 11>; 12export const get_publication_data = makeRoute({ 13 route: "get_publication_data", 14 input: z.object({ 15 did: z.string(), 16 publication_name: z.string(), 17 }), 18 handler: async ( 19 { did, publication_name }, 20 { supabase }: Pick<Env, "supabase">, 21 ) => { 22 let pubLeafletUri; 23 let siteStandardUri; 24 if (/^(?!\.$|\.\.S)[A-Za-z0-9._:~-]{1,512}$/.test(publication_name)) { 25 pubLeafletUri = AtUri.make( 26 did, 27 ids.PubLeafletPublication, 28 publication_name, 29 ).toString(); 30 siteStandardUri = AtUri.make( 31 did, 32 ids.SiteStandardPublication, 33 publication_name, 34 ).toString(); 35 } 36 let { data: publication, error } = await supabase 37 .from("publications") 38 .select( 39 `*, 40 documents_in_publications(documents( 41 *, 42 comments_on_documents(count), 43 document_mentions_in_bsky(count) 44 )), 45 publication_subscriptions(*, identities(bsky_profiles(*))), 46 publication_domains(*), 47 leaflets_in_publications(*, 48 documents(*), 49 permission_tokens(*, 50 permission_token_rights(*), 51 custom_domain_routes!custom_domain_routes_edit_permission_token_fkey(*) 52 ) 53 )`, 54 ) 55 .or(`name.eq."${publication_name}", uri.eq."${pubLeafletUri}", uri.eq."${siteStandardUri}"`) 56 .eq("identity_did", did) 57 .single(); 58 59 let leaflet_data = await getFactsFromHomeLeaflets.handler( 60 { 61 tokens: 62 publication?.leaflets_in_publications.map( 63 (l) => l.permission_tokens?.root_entity!, 64 ) || [], 65 }, 66 { supabase }, 67 ); 68 69 // Pre-normalize documents from documents_in_publications 70 const documents = (publication?.documents_in_publications || []) 71 .map((dip) => { 72 if (!dip.documents) return null; 73 const normalized = normalizeDocumentRecord(dip.documents.data, dip.documents.uri); 74 if (!normalized) return null; 75 return { 76 uri: dip.documents.uri, 77 record: normalized, 78 indexed_at: dip.documents.indexed_at, 79 data: dip.documents.data, 80 commentsCount: dip.documents.comments_on_documents[0]?.count || 0, 81 mentionsCount: dip.documents.document_mentions_in_bsky[0]?.count || 0, 82 }; 83 }) 84 .filter((d): d is NonNullable<typeof d> => d !== null); 85 86 // Pre-filter drafts (leaflets without published documents, not archived) 87 const drafts = (publication?.leaflets_in_publications || []) 88 .filter((l) => !l.documents) 89 .filter((l) => !(l as { archived?: boolean }).archived) 90 .map((l) => ({ 91 leaflet: l.leaflet, 92 title: l.title, 93 permission_tokens: l.permission_tokens, 94 // Keep the full leaflet data for LeafletList compatibility 95 _raw: l, 96 })); 97 98 return { 99 result: { 100 publication, 101 documents, 102 drafts, 103 leaflet_data: leaflet_data.result, 104 }, 105 }; 106 }, 107});